Diagnose when reverse_iterator is used on path::iterator. path::iterator isn't a strictly conforming iterator. Specifically it stashes the current element inside the iterator. This leads to UB when used with reverse_iterator since it requires the element to outlive the lifetime of the iterator. This patch adds a static_assert inside reverse_iterator to disallow "stashing iterator types", and it tags path::iterator as such a type. Additionally this patch removes all uses of reverse_iterator<path::iterator> within the tests. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@300164 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/iterator b/include/iterator index b8f6570..66d1a31 100644 --- a/include/iterator +++ b/include/iterator 
@@ -615,6 +615,14 @@  return __x;  }   + +template <class _Tp, class = void> +struct __is_stashing_iterator : false_type {}; + +template <class _Tp> +struct __is_stashing_iterator<_Tp, typename __void_t<typename _Tp::__stashing_iterator_tag>::type> + : true_type {}; +  template <class _Iter>  class _LIBCPP_TEMPLATE_VIS reverse_iterator  : public iterator<typename iterator_traits<_Iter>::iterator_category, @@ -625,6 +633,11 @@  {  private:  /*mutable*/ _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break + + static_assert(!__is_stashing_iterator<_Iter>::value, + "The specified iterator type cannot be used with reverse_iterator; " + "Using stashing iterators with reverse_iterator causes undefined behavior"); +  protected:  _Iter current;  public: